home *** CD-ROM | disk | FTP | other *** search
- /* hpalib_audio.c
- vi:ts=3 sw=3:
- */
-
- /* port to hp using the Alib library */
- /* $Id: alib_audio.c,v 1.6 1995/05/15 12:19:17 espie Exp espie $
- * $Log: alib_audio.c,v $
- * Revision 1.6 1995/05/15 12:19:17 espie
- * Hp port updated.
- *
- * Revision 1.5 1995/05/11 12:04:13 espie
- * Stupid typo.
- *
- * Revision 1.4 1995/02/23 16:42:27 espie
- * Began conversion to `common' model.
- *
- * Revision 1.3 1995/02/23 14:04:53 espie
- * primary/secondary -> pps/pms.
- *
- * Revision 1.2 1995/02/21 17:57:55 espie
- * Internal problem: RCS not working.
- *
- * Revision 1.1 1995/02/01 16:43:47 espie
- * Initial revision
- *
- * Revision 1.1 1995/02/01 16:43:47 espie
- * Initial revision
- *
- * Revision 1.2 1993/12/04 16:12:50 espie
- * BOOL -> boolean.
- *
- * Revision 1.1 1993/07/14 16:33:41 espie
- * Initial revision
- *
- */
-
- #include "defs.h"
- #include "extern.h"
- #include <audio/Alib.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
-
- ID("$Id: alib_audio.c,v 1.6 1995/05/15 12:19:17 espie Exp espie $")
-
-
- #define DEFAULT_BUFFERS
- #define DEFAULT_SET_MIX
- #define NEW_OUTPUT_SAMPLES_AWARE
- #include "Arch/common.c"
-
- Audio *audio; /* AUDIO connection for Alib, like DISPLAY for Xlib */
-
- LOCAL int freq; /* which frequency do we want? */
-
- AErrorHandler prevHandler; /* pointer to previous handler */
-
- LOCAL int audioPaused = True;
- LOCAL int streamSocket = 0;
- LOCAL int pauseCount;
-
- LOCAL short *bufBase = NULL;
- LOCAL long inLen;
-
- LOCAL ATransID xid;
-
- LOCAL AConvertParams *convert_params;
-
- LOCAL AudioAttrMask AttribsMask = 0, PlayAttribsMask = 0, ignoredMask = 0;
- LOCAL AudioAttributes Attribs, PlayAttribs;
- LOCAL AGainEntry gainEntry[4]; /* Need to be global since */
- /* PlayAttribs is global and it */
- /* contains a pointer to gainEntry */
- LOCAL SSPlayParams streamParams;
-
- extern char use_speaker;
- extern AGainDB volume;
-
-
- long myErrorHandler(audio, err_event)
- Audio *audio;
- AErrorEvent *err_event;
- {
- char errorbuf[132];
-
- AGetErrorText(audio, err_event->error_code, errorbuf, 131);
- end_all(errorbuf);
- }
-
-
- void create_playstream()
- {
- LOCAL SStream audioStream;
-
- /*
- * Initiate transaction.
- */
- xid = APlaySStream(audio, ~0, &PlayAttribs, &streamParams,
- &audioStream, NULL);
-
- /*
- * Create a stream socket.
- */
- streamSocket = socket(AF_INET, SOCK_STREAM, 0);
- if(streamSocket < 0) {
- end_all("Socket creation failed");
- }
-
- /*
- * Connect the stream socket to the audio stream port.
- */
- if (connect(streamSocket,
- (struct sockaddr *)&audioStream.tcp_sockaddr,
- sizeof(struct sockaddr_in)) < 0) {
- end_all("Connect failed");
- }
- }
-
-
- int open_audio(f, s)
- int f;
- int s;
- {
- char *pSpeaker;
- int seekOffset, data_length;
- AByteOrder play_byte_order, byte_order;
-
-
- audio = AOpenAudio(NULL, NULL);
-
- if (!audio) {
- end_all("Error opening audio device");
- }
-
- /* replace default error handler */
- prevHandler = ASetErrorHandler(myErrorHandler);
-
- stereo = s;
- if (stereo) {
- Attribs.attr.sampled_attr.channels = 2;
- AttribsMask |= (AttribsMask | ASChannelsMask);
- }
-
- /*
- * Get the best attributes from the server?
- */
- if (f <= 0) {
- AudioAttributes *bestAttr;
-
- bestAttr = ABestAudioAttributes(audio);
- freq = bestAttr->attr.sampled_attr.sampling_rate;
- } else
- freq = f;
-
- PlayAttribs.attr.sampled_attr.sampling_rate = freq;
- PlayAttribsMask |= ASSamplingRateMask;
-
- Attribs.attr.sampled_attr.sampling_rate = freq;
- AttribsMask |= ASSamplingRateMask;
-
- AChooseSourceAttributes(audio, NULL, NULL, AFFRawLin16,
- AttribsMask, &Attribs, &seekOffset,
- &data_length, &byte_order, NULL);
-
- AChoosePlayAttributes(audio, &Attribs, PlayAttribsMask,
- &PlayAttribs, &play_byte_order, NULL);
-
- /*
- * Prepare for conversion.
- * Must remember to free convert_params by calling AEndConversion.
- */
- convert_params = ASetupConversion(audio, &Attribs, &byte_order,
- &PlayAttribs, &play_byte_order, NULL);
-
- /*
- * Use the external jack, unless the user overrides this on the
- * command-line, or SPEAKER is set. (The command line stuff is done in
- * main.c.)
- */
- {
- char *speaker;
- if ((speaker = getenv("SPEAKER")) != NULL) {
- if ((*speaker == 'i') || (*speaker == 'I')) {
- use_speaker = 1;
- }
- }
- }
-
- switch (PlayAttribs.attr.sampled_attr.channels) {
-
- case 1: /* Mono */
- gainEntry[0].u.o.out_ch = AOCTMono;
- gainEntry[0].gain = volume;
- gainEntry[0].u.o.out_dst
- = (use_speaker) ? AODTMonoIntSpeaker : AODTMonoJack;
- break;
-
- case 2: /* Stereo */
- default:
- gainEntry[0].u.o.out_ch = AOCTLeft;
- gainEntry[0].gain = volume;
- gainEntry[0].u.o.out_dst
- = (use_speaker) ? AODTLeftIntSpeaker : AODTLeftJack;
- gainEntry[1].u.o.out_ch = AOCTRight;
- gainEntry[1].gain = volume;
- gainEntry[1].u.o.out_dst
- = (use_speaker) ? AODTRightIntSpeaker : AODTRightJack;
- break;
- }
- streamParams.gain_matrix.type = AGMTOutput; /* gain matrix */
- streamParams.gain_matrix.num_entries
- = PlayAttribs.attr.sampled_attr.channels;
- streamParams.gain_matrix.gain_entries = gainEntry;
- streamParams.play_volume = AUnityGain; /* play volume */
- streamParams.priority = APriorityNormal; /* normal priority */
- streamParams.event_mask = 0; /* don't solicit any events */
-
- /*
- * Create an audio stream.
- */
- create_playstream();
-
- /*
- * Calculate the required buffer size for the data prior to conversion
- * and allocate memory for the pre-converted data.
- */
- inLen = ACalculateLength(audio, audio->block_size,
- &PlayAttribs, &Attribs, NULL);
- buffer16 = malloc(inLen);
- idx = 0;
-
- /*
- * Allocate a buffer for the converted data.
- */
- bufBase = malloc(inLen);
-
- /*
- * Start stream paused so we can transfer enough data (3 seconds worth)
- * before playing starts to prevent stream from running out.
- */
- APauseAudio(audio, xid, NULL, NULL);
- pauseCount = 3
- * PlayAttribs.attr.sampled_attr.channels
- * PlayAttribs.attr.sampled_attr.sampling_rate
- * (PlayAttribs.attr.sampled_attr.bits_per_sample >> 3);
- audioPaused = True;
-
- freq = PlayAttribs.attr.sampled_attr.sampling_rate;
-
- if (freq != f)
- {
- static char buf[50];
- sprintf(buf, "Frequency used is %d\n", freq);
- notice(buf);
- }
-
- set_mix(30);
-
- return freq;
- }
-
-
- void output_samples(left, right, n)
- int left, right, n;
- {
- if (idx > inLen - 2)
- flush_buffer();
-
- add_samples16(left, right, n);
- }
-
-
- void discard_buffer()
- {
- /*
- * Destroy old playstream.
- */
- AStopAudio(audio, xid, ASMThisTrans, NULL, NULL);
- close(streamSocket);
- streamSocket = 0;
-
- /*
- * Recreate new playstream.
- */
- create_playstream();
- idx = 0;
- }
-
-
- void flush_buffer()
- {
- int len_written = 0, len, bytes_written, bytes_read;
- short *buf = buffer16;
-
- /*
- * Convert buffer
- */
- AConvertBuffer(audio, convert_params, buffer16, idx * sizeof(short),
- bufBase, inLen, &bytes_read, &bytes_written, NULL);
- len = bytes_written;
- buf = bufBase;
-
- /*
- * Write the converted data to the stream socket
- */
- while (len) {
- /*
- * write converted data to stream socket until we have emptied buffer
- */
- if ((len_written = write(streamSocket, buf, len)) < 0) {
- end_all("Write failed");
- }
- buf += len_written;
- len -= len_written;
-
- if (audioPaused) {
- pauseCount -= len_written;
- if (len_written == 0 || pauseCount <= 0) {
- AResumeAudio(audio, xid, NULL, NULL);
- audioPaused = False;
- }
- }
- }
- idx = 0;
- }
-
-
- void close_audio()
- {
- int bytes_written;
-
-
- if (audioPaused) {
- AResumeAudio(audio, xid, NULL, NULL);
- }
- /*
- * Free the convert_params structure and flush out
- * the conversion pipeline
- */
- AEndConversion(audio, convert_params, bufBase,
- audio->block_size, &bytes_written, NULL);
-
- ASetCloseDownMode(audio, AKeepTransactions, NULL);
- ASetErrorHandler(prevHandler);
- ACloseAudio(audio, NULL);
-
- if (streamSocket) close(streamSocket);
- if (buffer16) free(buffer16);
- if (bufBase) free(bufBase);
-
- end_all(0);
- }
-
-
- int update_frequency()
- {
- /* not implemented */
- return 0;
- }
-
-
- void set_synchro(sync)
- int sync;
- {
- /* if (streamSocket) {
- if (sync)
- setsockopt(streamSocket, SOL_SOCKET, TCP_NODELAY, 1);
- else
- setsockopt(streamSocket, SOL_SOCKET, TCP_NODELAY, 0);
- }*/
- }
-